/*
 * @Author: shiguang
 * @Date: 2023-04-26 10:23:12
 * @LastEditors: yusha
 * @LastEditTime: 2023-09-28 10:17:51
 * @Description: utils
 */

import pkg from '../../package.json';
import { GetKeyByMap, GetValueByMap } from './type';
const { REQUEST_ENV } = pkg._dev;
enum ENUM_PICK_MAP_TYPE {
    /** 选择 map 中部分 key 映射到 options */
    PICK = 1,
    /** 剔除 map 中部分 key 映射到 options */
    OMIT = 2,
    /** 所有 map 中 key 映射到 options */
    ALL = 3,
}

const originMapToOptions =
    <T extends Map<any, any>>(map: T) =>
        (type: ENUM_PICK_MAP_TYPE) =>
            (keys: GetKeyByMap<T>[]) =>
                <Fn extends (val: GetValueByMap<T>[0]) => any>(mapValue?: Fn):
                    ({
                        value: GetKeyByMap<T>;
                        label: (typeof mapValue) extends undefined ? GetKeyByMap<T> : ReturnType<Fn>;
                    })[] => {
                    const list = Array.from(map.entries()).filter(([value]) => {
                        if (type === ENUM_PICK_MAP_TYPE.OMIT && !keys.includes(value)) return true;
                        if (type === ENUM_PICK_MAP_TYPE.PICK && keys.includes(value)) return true;
                        if (type === ENUM_PICK_MAP_TYPE.ALL) return true;
                        return false;
                    });
                    return list.map(([value, label]) => ({ value, label: mapValue ? mapValue(label) : label }));
                };

/**
 * map options
 * @param map
 * @param mapValue
 * @returns
 */
export const mapToOptions = <T extends Map<any, any>, Fn extends (val: GetValueByMap<T>) => any>
    (map: T, mapValue?: Fn) => {
    return originMapToOptions(map)(ENUM_PICK_MAP_TYPE.ALL)([])(mapValue);
};

export const mapToOptionsByOmitKeys = <T extends Map<any, any>, Fn extends (val: GetValueByMap<T>[0]) => any>
    (map: T, keys: GetKeyByMap<T>[], mapValue?: Fn) => {
    return originMapToOptions(map)(ENUM_PICK_MAP_TYPE.OMIT)(keys)(mapValue);
};


export const mapToOptionsByPickKeys = <T extends Map<any, any>, Fn extends (val: GetValueByMap<T>[0]) => any>
    (map: T, keys: GetKeyByMap<T>[], mapValue?: Fn) => {
    return originMapToOptions(map)(ENUM_PICK_MAP_TYPE.PICK)(keys)(mapValue);
};

/**
 * 获取查询字符串中的值
 * @param name query string 的 key
 * @returns value
 */
export const getQueryStringValueByName = (name: string) => {
    return new URLSearchParams(window.location.search).get(name);
};


export const secureJSONParse = <T>(str: any, defaultValue?: T) => {
    type SecureJSONParseStore = [Error | undefined, T | undefined];
    const res: SecureJSONParseStore = [undefined, undefined];
    try {
        const obj = JSON.parse(str);
        res[1] = obj ?? defaultValue;
    } catch (e) {
        res[0] = e as Error;
        if (defaultValue) res[1] = defaultValue;
    }
    return res;
};

export const getSessionStorageByKey = <T>(key: string, defaultValue?: T) => {
    const jsonString = window.sessionStorage.getItem(key);
    return secureJSONParse(jsonString, defaultValue);
};

export const getLocalStorageByKey = <T>(key: string, defaultValue?: T) => {
    const jsonString = window.localStorage.getItem(key);
    return secureJSONParse(jsonString, defaultValue);
};

export const getLocalStorageJSONByKey = <T>(key: string, defaultValue?: T) => {
    const jsonString = window.localStorage.getItem(key);
    return secureJSONParse(jsonString, defaultValue);
};
/**
 * 获取uuid
 * @returns
 */
export const genUuid = () => {
    let d = new Date().getTime();
    const uuid = 'xxxxxxxxxxxxxxxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        // eslint-disable-next-line
        return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
    });
    return uuid;
};

interface JumptoOtherSystemOptions{
    pathname: string;
    query?: Record<string, string>;
}

export const getHostEnv = () => {
    const hostname = window.location.hostname;
    if(!hostname.includes('-')){
        return 'prod';
    }
    return hostname.split('-')[0];
};

export const jumptoOtherSystem = (options: JumptoOtherSystemOptions) => {
    const { pathname } = options;

    if(window.location.hostname === 'localhost'){
        // console.log(9999999888888, pathname);
        // 开发环境直接跳转的对应环境上
        window.location.href = `http://localhost:${window.location.port}${pathname}`;
        return;
    }
    // 部署在环境上的时候短路径处理 就 OK
    window.location.pathname = pathname;
};